package com.beiding.businessplatform.ql;

import java.util.HashSet;
import java.util.Set;

public class QueryTable {


    /*

        select _.id as id,_.subName as subName,_bs.id as bs_id,_bs.subName as bs_name
        from A _ left join _.bs bs left join _.bs.c bs_c
     */
    private QueryTable parent;

    private String tableName;

    //层
    private int layer;

    private QueryField idField;

    private Set<QueryField> allFields = new HashSet<>();
    private Set<QueryTable> allChildren = new HashSet<>();

    private String as;

    private String key;

    private boolean isRoot;

    public QueryTable(String tableName) {
        this.tableName = tableName;
        this.as = "$";
        layer = 0;
        isRoot = true;
        idField = makeField("id");
    }

    public QueryField getIdField() {
        return idField;
    }

    public Set<QueryField> getAllFields() {
        return allFields;
    }

    /*
    select $.id as id,bs.id as bs_id,bs_c.id as bs_c_id from A $ left join $.bs  bs left join bs.c bs_c
     */

    public int getLayer() {
        return layer;
    }

    public QueryTable getParent() {
        return parent;
    }

    private QueryTable(QueryTable parent, String name) {
        this.parent = parent;
        this.layer = parent.layer + 1;
        if (parent.isRoot) {
            this.key = "$." + name;
            this.as = name;
        } else {
            this.key = parent.as + "." + name;
            this.as = parent.as + "_" + name;
        }
        isRoot = false;
        idField = makeField("id");
    }

    public String getTableName() {
        return tableName;
    }

    public String getKey() {
        return key;
    }

    public String getAs() {
        return as;
    }

    public boolean isRoot() {
        return isRoot;
    }

    public QueryTable childTable(String child) {
        QueryTable table = new QueryTable(this, child);
        allChildren.add(table);
        return table;
    }

    public QueryField makeField(String name) {

        String key;
        String as;

        if (isRoot) {

            //key
            key = this.as + "." + name;
            as = name;

        } else {
            key = this.as + "." + name;
            as = this.as + "_" + name;
        }

        final boolean isAll = name.equals("*");

        final boolean isId = name.equals("id");

        QueryField queryField = new QueryField() {
            @Override
            public String getKey() {
                return key;
            }

            @Override
            public String getAs() {
                return as;
            }

            @Override
            public QueryTable getQueryTable() {
                return QueryTable.this;
            }

            @Override
            public boolean isId() {
                return isId;
            }

            @Override
            public boolean isAll() {
                return isAll;
            }
        };

        if (!isAll) {
            allFields.add(queryField);
        }

        if (name.equals("id")) {
            this.idField = queryField;
        }

        return queryField;

    }


    public QueryTable getRoot() {
        QueryTable t = this;

        while (true) {
            if (t.isRoot) {
                return t;
            }

            t = t.parent;
        }
    }


    public Set<QueryField> collectAllField() {
        Set<QueryField> all = new HashSet<>();
        collectAllField(all);
        return all;
    }

    public void collectAllField(Set<QueryField> all) {
        all.addAll(this.allFields);
        for (QueryTable child : allChildren) {
            child.collectAllField(all);
        }
    }
}
